﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartMathLibrary.LinearEquationSolvers
{
    /// <summary>
    /// This class provides methods to solve a linear system by using the elimination algorithm 
    /// of Gauss.
    /// </summary>
    [Serializable]
    public class GaussLinearSystemSolver
    {
        /// <summary>
        /// The system of equation to solve.
        /// </summary>
        private readonly LinearEquationSystem equationSystem;

        /// <summary>
        /// Initializes a new instance of the <see cref="GaussLinearSystemSolver"/> class.
        /// </summary>
        /// <param name="coefficientMatrix">The coefficient matrix of the equation system to solve.</param>
        /// <param name="resultVector">The result vector of the equation system to solve.</param>
        public GaussLinearSystemSolver(Matrix coefficientMatrix, GeneralVector resultVector)
        {
            this.equationSystem = new LinearEquationSystem(coefficientMatrix, resultVector);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GaussLinearSystemSolver"/> class.
        /// </summary>
        /// <param name="equationSystem">The system of equation to solve.</param>
        public GaussLinearSystemSolver(LinearEquationSystem equationSystem)
        {
            this.equationSystem = equationSystem;
        }

        /// <summary>
        /// Gets or sets the coefficient matrix of the equation system to solve.
        /// </summary>
        /// <value>The coefficient matrix of the equation system to solve.</value>
        public Matrix CoefficientMatrix
        {
            get { return equationSystem.CoefficientMatrix; }
            set { equationSystem.CoefficientMatrix = value; }
        }

        /// <summary>
        /// Gets or sets the result vector of the equation system to solve.
        /// </summary>
        /// <value>The result vector of the equation system to solve.</value>
        public GeneralVector ResultVector
        {
            get { return equationSystem.ResultVector; }
            set { equationSystem.ResultVector = value; }
        }

        /// <summary>
        /// Solves the linear system of equation by using the elimination algorithm of Gauss.
        /// </summary>
        /// <returns>The results of the system of equation.</returns>
        public GeneralVector SolveLinearSystem()
        {
            Matrix workingMatrix = Matrix.UnionMatricesVertical(this.CoefficientMatrix,
                                                                this.ResultVector.ToMatrix()).Copy();

            return new GeneralVector(workingMatrix.SolveLinearSystem());
        }
    }
}